package cn.stylefeng.guns.modular.business.app.service.impl;

import cn.stylefeng.guns.modular.business.app.mapper.PayOrderConfigMapper;
import cn.stylefeng.guns.modular.business.app.mapper.PayOrderMapper;
import cn.stylefeng.guns.modular.business.app.pojo.PayOrder;
import cn.stylefeng.guns.modular.business.app.pojo.PayOrderConfig;
import cn.stylefeng.guns.modular.business.app.service.ApiPayCallBackService;
import cn.stylefeng.guns.modular.business.frequency.finance.entity.Finance;
import cn.stylefeng.guns.modular.business.frequency.finance.mapper.FinanceMapper;
import cn.stylefeng.guns.modular.business.frequency.financedetail.mapper.FinanceDetailMapper;
import cn.stylefeng.guns.modular.business.frequency.financesettlement.entity.FinanceSettlementNoFill;
import cn.stylefeng.guns.modular.business.frequency.financesettlement.mapper.FinanceSettlementMapper;
import cn.stylefeng.guns.modular.business.frequency.financesettlement.mapper.FinanceSettlementNoFillMapper;
import cn.stylefeng.guns.modular.business.frequency.orderfinish.model.param.OrderFinishRecordVO;
import cn.stylefeng.guns.modular.business.frequency.orderfinishrecord.mapper.OrderFinishRecordMapper;
import cn.stylefeng.guns.modular.business.frequency.orderfinishrecord.service.OrderFinishRecordService;
import cn.stylefeng.guns.modular.business.frequency.ordersub.entity.OrderSub;
import cn.stylefeng.guns.modular.business.frequency.ordersub.mapper.OrderSubMapper;
import cn.stylefeng.guns.modular.business.util.BusinessUtil;
import cn.stylefeng.guns.sys.modular.user.constant.ApiPayConstant;
import cn.stylefeng.guns.sys.modular.user.entity.SysUser;
import cn.stylefeng.guns.sys.modular.user.mapper.SysUserMapper;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.huifu.bspay.sdk.opps.core.utils.RsaUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class ApiPayCallBackServiceImpl implements ApiPayCallBackService {

    @Autowired
    private PayOrderMapper payOrderMapper;

    @Autowired
    private FinanceMapper financeMapper;

    @Autowired
    private OrderSubMapper orderSubMapper;

    @Autowired
    private FinanceSettlementMapper financeSettlementMapper;

    @Autowired
    private FinanceDetailMapper financeDetailMapper;

    @Autowired
    private BusinessUtil businessUtil;

    @Resource
    private OrderFinishRecordMapper orderFinishRecordMapper;

    @Autowired
    private PayOrderConfigMapper payOrderConfigMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Resource
    private OrderFinishRecordService finishService;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private FinanceSettlementNoFillMapper financeSettlementNoFillMapper;

    @Override
    public String handler(HttpServletRequest request) {
        //获取响应数据
        String data = request.getParameter("resp_data");

        //获取签名信息
        String sign = request.getParameter("sign");

        //进行验签
        if (!RsaUtils.verify(data, ApiPayConstant.RSA_PUBLIC_KEY, sign)) {
            //验签失败直接退出方法
            return "";
        }


        // 将data转换为json对象
        JSONObject jsonObject = JSON.parseObject(data);
        // 获取请求id
        String reqSeqId = jsonObject.getString("req_seq_id");
        // 获取请求时间
        String reqDate = jsonObject.getString("req_date");

        // 根据请求流水号和请求时间，并查询订单对象
        PayOrder payOrder = payOrderMapper.selectOne(new LambdaQueryWrapper<PayOrder>()
                .eq(PayOrder::getReqDate, reqDate)
                .eq(PayOrder::getReqSeqId, reqSeqId));

        // 如果查询的结果为空直接返回
        if (Objects.isNull(payOrder)) {
            return "";
        }

        // 如果订单已经是完成状态直接返回
        if (1 == payOrder.getStatus()) {
            return "RECV_ORD_ID_" + reqSeqId;
        }

        //获取交易状态
        String transStat = jsonObject.getString("trans_stat");
        //将交易的状态同步到数据库中
        payOrder.setStatus("S".equals(transStat) ? 1 : 2);

        //执行更新
        payOrderMapper.updateById(payOrder);

        //如果交易状态是成功时，需要修改订单相关信息
        if ("S".equals(transStat)) {
            updateOrder(payOrder);
        }


        return "RECV_ORD_ID_" + reqSeqId;
    }

    /**
     * 修改订单相关信息
     */
    private void updateOrder(PayOrder payOrder) {
        Integer payType = payOrder.getPayType();

        switch (payType) {
            case 1:
                do1(payOrder);
                break;
            case 2:
                do2(payOrder);
                break;
            case 3:
                do3(payOrder);
                break;
            case 4:
                do4(payOrder);
                break;
            case 5:
                do5(payOrder);
                break;
        }
    }

    private void do5(PayOrder payOrder) {
        //根据订单id查询财务信息表
        Finance finance = getFinance(payOrder);

        //将欠付已付加上支付金额
        //将欠付未付减去支付金额
        finance.setBackHas(finance.getBackHas().add(new BigDecimal(payOrder.getTransAmt())));
        finance.setBackUn(finance.getBackUn().subtract(new BigDecimal(payOrder.getTransAmt())));
        updateCollectionStatus(finance);
        financeMapper.updateById(finance);

        //订单的创建人就是当前登录的用户id
        SysUser sysUser = sysUserMapper.selectById(payOrder.getCreateBy());

        //保存日记账
        FinanceSettlementNoFill financeSettlement = new FinanceSettlementNoFill();
        setCommonValue(financeSettlement, sysUser);
        // 结算类型为欠付
        financeSettlement.setType(3);
        financeSettlement.setOrderId(finance.getOrderId());
        financeSettlement.setSettlementFee(new BigDecimal(payOrder.getTransAmt()));
        financeSettlementNoFillMapper.insert(financeSettlement);
    }

    /**
     * 交付页面支付成功后逻辑处理
     */
    private void do2(PayOrder payOrder) {

        String redisKey = ApiPayConstant.DELIVERY_COMPLETED + "_" + payOrder.getOrderId();
        //调用原来的接口
        OrderFinishRecordVO orderFinishRecordVO = (OrderFinishRecordVO) redisTemplate.opsForValue().get(redisKey);
        Long userId = payOrder.getCreateBy();
        Long tenantId = payOrder.getTenantId();
        finishService.finish(userId, orderFinishRecordVO, tenantId);

        //将redis数据删除
        redisTemplate.delete(redisKey);

        //将用逗号分隔的订单字符串转换为List<Long>
        String orderId = payOrder.getOrderId();
        String[] split = orderId.split(",");
        List<Long> list = Arrays.stream(split).map(Long::valueOf).collect(Collectors.toList());

        //订单的创建人就是当前登录的用户id
        SysUser sysUser = sysUserMapper.selectById(payOrder.getCreateBy());

        //将已经完成现付的线上支付订单保存起来，并且还要保存日记账
        for (Long aLong : list) {

            //根据id查询订单财务信息表记录
            Finance finance = financeMapper.selectOne(new LambdaQueryWrapper<Finance>()
                    .eq(Finance::getOrderId, aLong));

            //保存日记账
            FinanceSettlementNoFill financeSettlement = new FinanceSettlementNoFill();
            setCommonValue(financeSettlement, sysUser);

            // 结算类型为到付
            financeSettlement.setType(2);
            financeSettlement.setOrderId(aLong);
            if (finance != null) {
                financeSettlement.setSettlementFee(finance.getDeliveryUn());
            }
            financeSettlementNoFillMapper.insert(financeSettlement);

            //将到付已付加上到付未付金额
            //将到付未付清0
            assert finance != null;
            finance.setDeliveryHas(finance.getDeliveryHas().add(finance.getDeliveryUn()));
            finance.setDeliveryUn(new BigDecimal("0"));
            updateCollectionStatus(finance);
            financeMapper.updateById(finance);

            //将订单表中的状态修改为7已完成
            if (finance.getCollectionStatus() == 2) {
                OrderSub orderSub = orderSubMapper.selectById(aLong);
                orderSub.setStatus(7);
                orderSubMapper.updateById(orderSub);
            }
        }
    }

    /**
     * 网点代收线上支付成功后逻辑处理
     */
    private void do1(PayOrder payOrder) {
        //根据订单id查询财务信息表
        Finance finance = getFinance(payOrder);

        //将现付已付加上支付金额
        //将现付未付减去支付金额
        finance.setDeliveryHas(finance.getDeliveryHas().add(new BigDecimal(payOrder.getTransAmt())));
        finance.setDeliveryUn(finance.getDeliveryUn().subtract(new BigDecimal(payOrder.getTransAmt())));
        updateCollectionStatus(finance);
        financeMapper.updateById(finance);

        //订单的创建人就是当前登录的用户id
        SysUser sysUser = sysUserMapper.selectById(payOrder.getCreateBy());

        //保存日记账
        FinanceSettlementNoFill financeSettlement = new FinanceSettlementNoFill();
        setCommonValue(financeSettlement, sysUser);
        // 结算类型为到付
        financeSettlement.setType(2);
        financeSettlement.setOrderId(finance.getOrderId());
        financeSettlement.setSettlementFee(new BigDecimal(payOrder.getTransAmt()));
        financeSettlementNoFillMapper.insert(financeSettlement);
    }

    /**
     * 订单创建完成后现金线上支付成功后逻辑处理
     */
    private void do4(PayOrder payOrder) {
        //根据订单id查询财务信息表
        Finance finance = getFinance(payOrder);

        //将现付已付加上支付金额
        //将现付未付减去支付金额
        finance.setSpotHas(finance.getSpotHas().add(new BigDecimal(payOrder.getTransAmt())));
        finance.setSpotUn(finance.getSpotUn().subtract(new BigDecimal(payOrder.getTransAmt())));
        updateCollectionStatus(finance);
        financeMapper.updateById(finance);

        //保存订单id
        PayOrderConfig payOrderConfig = new PayOrderConfig();
        payOrderConfig.setOrderId(finance.getOrderId());
        payOrderConfigMapper.insert(payOrderConfig);

        //订单的创建人就是当前登录的用户id
        SysUser sysUser = sysUserMapper.selectById(payOrder.getCreateBy());

        //保存日记账
        FinanceSettlementNoFill financeSettlement = new FinanceSettlementNoFill();
        setCommonValue(financeSettlement, sysUser);
        // 结算类型为现付
        financeSettlement.setType(1);
        financeSettlement.setOrderId(finance.getOrderId());
        financeSettlement.setSettlementFee(new BigDecimal(payOrder.getTransAmt()));
        financeSettlement.setCreateUser(payOrder.getCreateBy());
        financeSettlementNoFillMapper.insert(financeSettlement);
    }

    /**
     * 根据订单id查询订单财务信息
     */
    private Finance getFinance(PayOrder payOrder) {
        return financeMapper.selectOne(new LambdaQueryWrapper<Finance>()
                .eq(Finance::getOrderId, Long.valueOf(payOrder.getOrderId())));
    }

    /**
     * 判断未收合计是否为0，如果为0将collectionStatus设置为2
     */
    private void updateCollectionStatus(Finance finance) {
        BigDecimal bigDecimal1 = new BigDecimal("0");
        if (finance.getSpotUn() != null) {
            bigDecimal1 = bigDecimal1.add(finance.getSpotUn());
        }
        if (finance.getDeliveryUn() != null) {
            bigDecimal1 = bigDecimal1.add(finance.getDeliveryUn());
        }
        if (finance.getBackUn() != null) {
            bigDecimal1 = bigDecimal1.add(finance.getBackUn());
        }
        if (finance.getSlotUn() != null) {
            bigDecimal1 = bigDecimal1.add(finance.getSlotUn());
        }
        if (0 == Double.parseDouble(bigDecimal1.toString())) {
            finance.setCollectionStatus(2);
        }
    }

    public static void main(String[] args) {
        String s = "12536,45632,899456";
        String[] split = s.split(",");
        List<Long> list = Arrays.stream(split).map(Long::valueOf).collect(Collectors.toList());
        System.out.println(list);
    }

    /**
     * 创建订单时现金线上支付成功后逻辑处理
     */
    private void do3(PayOrder payOrder) {
        //将用逗号分隔的订单字符串转换为List<Long>
        String orderId = payOrder.getOrderId();
        String[] split = orderId.split(",");
        List<Long> list = Arrays.stream(split).map(Long::valueOf).collect(Collectors.toList());


        //将订单金额除以订单数量，得到每个订单的现付金额
        String transAmt = payOrder.getTransAmt();
        BigDecimal bigDecimal = new BigDecimal(transAmt);
        bigDecimal = bigDecimal.divide(new BigDecimal(list.size()), 2, RoundingMode.HALF_UP);

        //订单的创建人就是当前登录的用户id
        SysUser sysUser = sysUserMapper.selectById(payOrder.getCreateBy());

        //将已经完成现付的线上支付订单保存起来，并且还要保存日记账
        for (Long aLong : list) {
            //保存订单id
            PayOrderConfig payOrderConfig = new PayOrderConfig();
            payOrderConfig.setOrderId(aLong);
            payOrderConfigMapper.insert(payOrderConfig);

            //保存日记账
            FinanceSettlementNoFill financeSettlement = new FinanceSettlementNoFill();
            setCommonValue(financeSettlement, sysUser);
            // 结算类型为现付
            financeSettlement.setType(1);
            financeSettlement.setOrderId(aLong);
            financeSettlement.setSettlementFee(bigDecimal);
            financeSettlementNoFillMapper.insert(financeSettlement);
        }

        //根据订单id查询订单财务信息表记录
        List<Finance> list1 = financeMapper.selectList(new LambdaQueryWrapper<Finance>()
                .in(Finance::getOrderId, list));

        //遍历集合
        //将现付已付加上支付金额
        //将现付未付减去支付金额
        for (Finance finance : list1) {
            finance.setSpotHas(finance.getSpotHas().add(bigDecimal));
            finance.setSpotUn(finance.getSpotUn().subtract(bigDecimal));
            updateCollectionStatus(finance);
            financeMapper.updateById(finance);
        }
    }

    /**
     * 设置日记账公共属性
     */
    private void setCommonValue(FinanceSettlementNoFill financeSettlement, SysUser user) {
        //获取当前登录用户
        //SysLoginUser user = LoginContextHolder.me().getSysLoginUser();


        //给属性赋值
        financeSettlement.setCreateTime(new Date());
        financeSettlement.setUpdateTime(new Date());
        financeSettlement.setCreateUser(user.getId());
        financeSettlement.setUpdateUser(user.getId());
        financeSettlement.setSettlementUser(user.getName());
        financeSettlement.setSettlementPhone(user.getPhone());
        financeSettlement.setSettlementTime(new Date());
        financeSettlement.setTenantId(user.getTenantId());

        //收款渠道 5 线上支付
        financeSettlement.setChannel(5);

        //设置为审核成功
        financeSettlement.setResult(3);
    }
}
